import java.util.List;
import java.util.Map;

import exception.NoMoreStepsException;
import exception.StatementExecutionException;

import runtime.ClassMapFactory;
import runtime.RootScopeFactory;
import statement.Statement;
import util.Attribute;
import util.Class;
import util.Reference;
import util.Scope;

/**
 * Klasa zbiorcza programu, laczaca ze soba parsowany skrypt oraz jego
 * wykonanie. Zostaje utworzona przez parser wygenerowany w Antlr. Po
 * zakonczeniu parsowania wywolana jest metoda run(), odpowiedzialna za
 * wykonanie sie skryptu.
 * 
 * @author jfibinger
 * 
 */
public class Program {
	/**
	 * Lista atrybutow - lista zadeklarowanych atrybutow - wszystkie deklaracje
	 * zmiennych, ktore bedzie sie wykorzystywac w skrypcie
	 */
	private List<Attribute> attributes;
	/**
	 * Lista polecen glownych procedury
	 */
	private List<Statement> statements;
	/**
	 * Zasieg zmiennych - zmienna przechowujaca referencje do wszystkich
	 * atrybutow, do ktorych mamy dostep z danego poziomu. W tym wypadku jest to
	 * zasieg bazowy - wszystkie metody maja dostep do tych zmiennych.
	 */
	private Scope rootScope;

	/**
	 * Konstruktor klasy Program
	 * 
	 * @param attributes lista deklaracji atrybutow
	 * @param statements lista polecen
	 */
	public Program(List<Attribute> attributes, List<Statement> statements) {
		super();
		this.attributes = attributes;
		this.statements = statements;
		this.rootScope = RootScopeFactory.getInstance().getRootScope();
	}

	/**
	 * Podstawowa metoda naszego interpretera - rozpoczyna wykonywanie programu
	 */
	public void run() {
		for (Attribute attr : attributes) {
			rootScope.addReference(new Reference(attr));
		}
		for (Statement stat : statements) {
			try {
				stat.execute();
			} catch (StatementExecutionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (NoMoreStepsException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}
}
